Skip to content

Conversation

@matej-douro
Copy link
Contributor

🚧 in progress 🚧

Summary

Implements support for Pyth governance messages provided as Wormhole VAAs, and exposes actions for initialization, upgrading and trusted signer updates. Updates xc_admin and contract_manager to support new types of messages and maintenance actions.

The PR adds a new "Lazer" module for governance actions related to Lazer contracts, as these don't map well to existing Core actions. From my understanding, existing Lazer contracts seem to use custom payload for governance, or do not consume governance messages at all, so they don't seem to be affected yet.

Rationale

How has this been tested?

  • Current tests cover my changes
  • Added new tests
  • Manually tested the code

I've updated and run lazer/contracts/sui test suite and extended (and run) xc_admin test suite to cover new messages.

@vercel
Copy link

vercel bot commented Dec 18, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
api-reference Error Error Jan 9, 2026 1:46pm
component-library Ready Ready Preview, Comment Jan 9, 2026 1:46pm
developer-hub Ready Ready Preview, Comment Jan 9, 2026 1:46pm
4 Skipped Deployments
Project Deployment Review Updated (UTC)
entropy-explorer Skipped Skipped Jan 9, 2026 1:46pm
insights Skipped Skipped Jan 9, 2026 1:46pm
proposals Skipped Skipped Jan 9, 2026 1:46pm
staking Skipped Skipped Jan 9, 2026 1:46pm

@matej-douro
Copy link
Contributor Author

Depends on #3317

@vercel vercel bot temporarily deployed to Preview – entropy-explorer December 18, 2025 17:17 Inactive
@vercel vercel bot temporarily deployed to Preview – staking December 18, 2025 17:17 Inactive
@vercel vercel bot temporarily deployed to Preview – developer-hub December 18, 2025 17:17 Inactive
@vercel vercel bot temporarily deployed to Preview – proposals December 18, 2025 17:17 Inactive
@vercel vercel bot temporarily deployed to Preview – api-reference December 18, 2025 17:17 Inactive
@vercel vercel bot temporarily deployed to Preview – insights December 18, 2025 17:17 Inactive
@vercel vercel bot temporarily deployed to Preview – component-library December 18, 2025 17:17 Inactive
Copy link
Collaborator

@ali-behjati ali-behjati left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i reviewed only the sui contract. it seems correct but i think the structure can be improved. There are mutations happening in both state.move and governance.move [on process incoming message] which makes reading hard. if possible, my recommendation is to keep state minimal and move all the business logic affecting state in governance.move file itself.

# supported, and testnet one is already outdated, so we either want to have the
# package at MVR at some point, or maybe want to consider creating our own
# branches with symlinked `Move.toml`.
rev = "sui/mainnet"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the story about this is that they were blocked on some issues with the move package manager handling multiple local packages to upgrade. they haven't fixed it yet

MystenLabs/sui#22194 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I see 🫤 I'm playing with custom testnet branch for now, but I wonder what branches to use after finishing the PR.

/// Reference:
/// https://wormhole.com/docs/products/reference/chain-ids/#__tabbed_1_1
/// https://github.com/pyth-network/pyth-crosschain/blob/b021cfe9b2716947f22d1724cd3fa7e3de6b026e/governance/xc_admin/packages/xc_admin_common/src/chains.ts#L274
const RECEIVER_CHAIN_ID: u16 = 21;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to make this a customizable parameter (initialized on package init)? we might deploy to multiple SUI-like networks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure - question is, given that meta module will already require source change for every individual deploy, whether it wouldn't make sense to put it there instead.
We could even generate meta on demand when building for specific chain and deploy. This way it's one less field to store on-chain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've implemented the latter approach, but let me know if it's better to do differently.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meta comment: couldn't we put it in governance.move?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will try to come up with a better structuring.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might want to use it for parsing payload data as well.

it's not super clear to me what value we get out of this wrapper. but it's fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just to decouple our parsing logic from wormhole, so that we can use method syntax and possibly add more methods later. Should I port over payload parsing, or leave it as it is for now?

Just a note - Parser type must be public because of language restrictions, but the module doesn't expose anything else outside of the package, so the API is de facto fully upgradeable. It will just require creating a new parser type as a replacement.

assert!(self.chain_id == chain_id, EMismatchedEmitterChainID);
assert!(self.address == address, EMismatchedAddress);
// TODO: See https://wormhole.com/docs/protocol/infrastructure/vaas/#verified-action-approvals
// - is this enough to avoid replay attacks?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically related to these paragraphs:

The sequence field depends on the final ordering of blocks on the emitter chain. When a lower consistency level is chosen (i.e., not waiting for finality), there is a chance that chain reorganizations could lead to multiple, different VAAs appearing for what looks like the “same” message on the user side.

The tuple (emitter_chain, emitter_address, sequence) can only be considered unique if the chain does not undergo a reorg and the block containing the message has effectively reached finality. However, there is always a small chance of an extended reorg that could invalidate or alter a previously emitted sequence number.

I left the comment here during PR just to address this - do we want to put lower bound on consistency level, or is it relevant at all in case of a Solana emitter?

/// would give them their current address or version, we track it manually here.
///
/// WARNING: Construction of `CurrentCap` requires this version to match the
/// `UpgradeCap` version, and thus attempts to publish or upgrade the package
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does the upgrade cap version change? does it increment by 1 each time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it should be incremented by one on every upgrade, starting with 1 on initial publish. I will try to automate this to avoid invalid upgrades once I finish the contract manager script.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See manage_sui_lazer_contract.ts.

} else if (header.action === "UpdateTrustedSigner") {
return fc
.record({
publicKey: hexBytesArb({ minLength: 33, maxLength: 33 }),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm why is it 33?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are supposed to be Bitcoin-style (secp256k1) ECDSA compressed keys, which are 32 bytes plus 1 byte prefix. Same as output of secp256k1_ecrecover during update verification.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add tests with fixtures for the governance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants